﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BLToolkit.Data;
using BLToolkit.Mapping;
using BLToolkit.DataAccess;
using BLToolkit.Data.Sql.SqlProvider;
using BLToolkit.Data.DataProvider;
using System.Runtime.Serialization;

namespace nwrole.toolbox.sync.entity
{
    [DataContract(Name="SyncMode")]
    public enum SyncModeEnum
    {
        [EnumMember]
        GhostSync = 0,
        [EnumMember]
        LastChangedSync = 1,
        [EnumMember]
        FileSync = 2,
    }

    [DataContract]
    [TableName("SyncEntity")]
    public class SyncEntity
    {
        [DataMember]
        [PrimaryKey, Identity, SequenceName("nwrole")]
        public int Id { get; set; }

        [DataMember]
        [MapField("SyncInstanceId")]
        public int SyncInstanceId { get; set; }

        [DataMember]
        [MapField("SyncMode")]
        public SyncModeEnum SyncMode { get; set; }

        [DataMember]
        [MapField("SortIndex")]
        public int SortIndex { get; set; }

        [DataMember]
        [MapField("Name")]
        public string Name { get; set; }

        [DataMember]
        [MapField("SourceTableName")]
        public string SourceTableName { get; set; }

        [DataMember]
        [MapField("SourceUpdatedColumnName")]
        public string SourceUpdatedColumnName { get; set; }

        [DataMember]
        [MapField("SourceInsertedColumnName")]
        public string SourceInsertedColumnName { get; set; }

        [DataMember]
        [MapField("SourceFilter")]
        public string SourceFilter { get; set; }

        [DataMember]
        [MapField("OverrideFilter")]
        public string OverrideFilter { get; set; }

        [DataMember]
        [MapField("ShadowTableName")]
        public string ShadowTableName { get; set; }

        [DataMember]
        [MapField("DestinationTableName")]
        public string DestinationTableName { get; set; }

        [DataMember]
        [MapField("TargetTableName")]
        public string TargetTableName { get; set; }

        [DataMember]
        [MapField("DestinationSyncCompleteSPName")]
        public string DestinationSyncCompleteSPName { get; set; }

        [DataMember]
        [MapField("SourceSyncStartSPName")]
        public string SourceSyncStartSPName { get; set; }

        [DataMember]
        [MapField("Type")]
        public short Type { get; set; }

        [DataMember]
        [MapField("SyncEnabled")]
        public int SyncEnabled { get; set; }

        [DataMember]
        [MapField("ExternalObjectId")]
        public long ExternalObjectId { get; set; }

        [MapIgnore]
        public DateTime? Create_date { get; set; }

        [MapIgnore]
        public DateTime? Modify_date { get; set; }

        [MapIgnore]
        public bool SyncEnabledBool
        {
            get
            {
                return SyncEnabled == 1 ? true : false;
            }
            set
            {
                if (value) SyncEnabled = 1; else SyncEnabled = 0;
            }
        }
        
        [DataMember]
        [MapField("SyncDat")]
        public DateTime? SyncDat { get; set; }

        [DataMember]
        [MapField("ImportDat")]
        public DateTime? ImportDat { get; set; }

        [DataMember]
        [MapField("DeploySourceDat")]
        public DateTime? DeploySourceDat { get; set; }

        [DataMember]
        [MapField("DeployDestinationDat")]
        public DateTime? DeployDestinationDat { get; set; }

        [DataMember]
        [MapField("EntityChangedDat")]
        public DateTime? EntityChangedDat { get; set; }

        [DataMember]
        [MapField("ResyncAll")]
        public int ResyncAll { get; set; }

        [DataMember]
        [MapField("SourceTimestampColumnName")]
        public string SourceTimestampColumnName { get; set; }

        [DataMember]
        [MapField("HighestTimestamp")]
        public System.Data.Linq.Binary HighestTimestamp { get; set; }

        [DataMember]
        [MapField("KeepDays")]
        public int KeepDays { get; set; }

        [DataMember]
        [MapField("LatestFileSync")]
        public DateTime? LatestFileSync { get; set; }

        // List<SyncMapColumn> _cols = new List<SyncMapColumn>();
        [DataMember]
        [Association(ThisKey = "Id", OtherKey = "SyncEntityId", CanBeNull = false)]
        public List<SyncEntityColumn> Columns { get; set; }

        [MapIgnore]
        [Association(ThisKey = "SyncInstanceId", OtherKey = "Id", CanBeNull = false)]
        public SyncInstance SyncInstance { get; set; }


        /*[DataMember]
        [MapField("TestStamp")]
        public System.Data.Linq.Binary TestStamp { get; set; }*/

        /*[DataMember]
        [MapField("TestStampCopy")]
        public System.Data.Linq.Binary TestStampCopy { get; set; }*/

        public SyncEntity()
        {
            Columns = new List<SyncEntityColumn>();
        }


        [MapIgnore]
        public IEnumerable<SyncEntityColumn> PrimaryKeyColumns
        {
            get
            {
                return Columns.Where(c => c.PrimaryKey);
            }
        }

        [MapIgnore]
        public IEnumerable<SyncEntityColumn> SyncEnabledColumns
        {
            get
            {
                return Columns.OrderBy(x => x.Id).Where(c => c.SyncEnabled == 1);
            }
        }

        [MapIgnore]
        public IEnumerable<SyncEntityColumn> NonPrimaryKeyColumns
        {
            get
            {
                return Columns.Where(c => !c.PrimaryKey);
            }
        }

        [MapIgnore]
        public SyncEntityColumn PrimaryKey
        {
            get
            {
                foreach (var column in Columns)
                {
                    if (column.PrimaryKey)
                    {
                        return column;
                    }
                }
                return null;
            }
        }

        public void AddColumn(string _ColumnName, string _CSharpType, string _SourceSqlType, bool _SourceNullable, string _DestSqlType, bool _DestNullable, bool _PrimaryKey)
        {
            SyncMapColumn column = new SyncMapColumn()
            {
                ColumnName = _ColumnName,
                CSharpType = _CSharpType,
                SourceSqlTypeNullableBool = _SourceNullable,
                SourceSqlTypeName = _SourceSqlType,
                DestSqlTypeName = _DestSqlType,
                DestSqlTypeNullableBool = _DestNullable,
                PrimaryKey = _PrimaryKey
            };
            AddColumn(column);
        }

        public void AddColumn(SyncEntityColumn col)
        {
            Columns.Add(col);
        }

        public string GetSchema()
        {
            StringBuilder sb = new StringBuilder();
            foreach (var column in SyncEnabledColumns)
            {
                sb.Append(column.GetSchema());
                sb.Append("\t");
            }
            sb.Length = sb.Length - 1; // ta bort sista \t
            return sb.ToString();
        }

        public static void Update(SyncEntity e, string srcConnectionStr, string syncConnectionStr)
        {
            SyncEntityRepository dal = new SyncEntityRepository();
            dal.SrcConnectionString = srcConnectionStr;
            dal.SyncConnectionString = syncConnectionStr;
            if (GlobalSettings.IsOracle)
            {
                //dal.DataProvider = new OdpDataProvider();
                throw new NotImplementedException();
            }
            else
            {
                dal.DataProvider = new SqlDataProvider();
            }

            dal.Update(e);
        }

        [MapIgnore]
        public string SyncEnabledString
        {
            get
            {
                if (SyncEnabled == 1) return "True";
                return "False";
            }
        }

    }
}
